import { JJUtil, JJLog } from '../util/index.js';
import JJError from './../bizUtil/JJError.js';
import JJLoginService from './../service/loginService/JJLoginService.js'

let requestCount = 0

export default class JJRequestAgent {
  
    static instance
    requestList = []
    readyRequestList= []

    static shareInstance() {
        if (false === this.instance instanceof this) {
            this.instance = new this;
        }
        return this.instance;
    }

    start(request) {
        if (JJLoginService.JJLoginServiceIdentityGetSecretkey == request.identity 
            || JJLoginService.JJLoginServiceIdentityNoPasswordLogin == request.identity 
            || JJLoginService.JJLoginServiceIdentityWechatLogin == request.identity) {
            this.__start(request)
            return
        }

        this.__startGetSecretkeyIfNeeded(request)
    }

    stop(request) {
        this.removeRequest(request);
    }

    handleNetworkSuccessRequestResult(request, response) {
        const index = this.requestList.indexOf(request);
        if (index < 0) {
            return;
        }

        this.removeRequest(request);

        request.responseCode = response.statusCode;
        request.responseData = response.data;
        request.responseHeader = response.header;

        request.requestCompleteFilter(request.responseData).then((value) => {
            const url = request.buildRequestUrl();
            JJLog.log(`(${++requestCount})` + request.toString())
            JJLog.log(`(${requestCount})` + '【Response Success】url: ' + url + '; content: ' + JSON.stringify(value));

            const isSuccess = request.successForBusiness(value)
            const result = request.filterSuccessCallBackValue(isSuccess, value)
            
            if (JJUtil.isNotNull(request.networkSuccessCallBack)) {
                request.networkSuccessCallBack(isSuccess, result, request.otherInfo);
            }

            if (request.isNeedPostResponseNotification) {
                request.postResponseNotification(isSuccess, result, null)
            }
        });
    }

    handleNetworkFailRequestResult(request, error) {
        const index = this.requestList.indexOf(request);
        if (index < 0) {
            return;
        }

        this.removeRequest(request);

        request.requestFailedFilter(error).then((value) => {            
            const errorObj = request.filterFailCallBackValue(value)
            if (JJUtil.isNotNull(request.networkFailCallBack)) {   
                request.networkFailCallBack(errorObj, request.otherInfo);  
            }
        });
    }

    addRequest(request) {
        const index = this.requestList.indexOf(request);
        if (index >= 0) {
            return;
        }
        this.requestList.push(request);
    }

    removeRequest(request) {
        const index = this.requestList.indexOf(request);
        if (index >= 0) {
            this.requestList.splice(index, 1);
        }
    }

    addRequestToReadyRequestList(request) {
        const index = this.readyRequestList.indexOf(request);
        if (index >= 0) {
            return;
        }
        this.readyRequestList.push(request);
    }

    removeRequestToReadyRequestList(request) {
        const index = this.readyRequestList.indexOf(request);
        if (index >= 0) {
            this.readyRequestList.splice(index, 1);
        }
    }

    __start(request) {
        this.addRequest(request);

        const url = request.buildRequestUrl();
        const header = request.getRequestHeader()
        const paramters = request.requestParameter();
        const method = request.methodType;
        const multipartFormData = request.multipartFormData;

        if (JJUtil.isNotNull(multipartFormData) && JJUtil.isNotNull(multipartFormData.name) && JJUtil.isNotNull(multipartFormData.filePath)) {
            if (!request.isAllowBeginUploadFile()) {
                this.handleNetworkFailRequestResult(request, JJError.networkReuqestFailError)
                return
            }

            wx.uploadFile({
                url: url,
                filePath: multipartFormData.filePath,
                name: multipartFormData.name,
                formData: paramters,
                success: function (response) {
                    if(JJUtil.isNotNull(response.data)){
                        response.data = JSON.parse(response.data);
                    }
                    if (response.statusCode >= 200 && response.statusCode <= 299) {
                        JJRequestAgent.shareInstance().handleNetworkSuccessRequestResult(request, response);
                    } else {
                        JJRequestAgent.shareInstance().handleNetworkFailRequestResult(request, response.data);
                    }
                },
                fail: function (error) {
                    JJLog.log(`(${++requestCount})` + request.toString())
                    JJLog.error(`(${requestCount})` + '【Response faile】url: ' + url + '; error: ' + JSON.stringify(error));
                    JJRequestAgent.shareInstance().handleNetworkFailRequestResult(request, error);
                },
                complete: function (res) { },
            })
        } else {
            if (!request.isAllowBeginSendRequest()) {
                this.handleNetworkFailRequestResult(request, JJError.networkReuqestFailError)
                return;
            }

            wx.request({
                url: url,
                header: header,
                data: paramters,
                method: method,
                success: function (response) {
                    if (response.statusCode >= 200 && response.statusCode <= 299) {
                        JJRequestAgent.shareInstance().handleNetworkSuccessRequestResult(request, response);
                    } else {
                        JJRequestAgent.shareInstance().handleNetworkFailRequestResult(request, response.data);
                    }
                },
                fail: function (error) {
                    JJLog.log(`(${++requestCount})` + request.toString())
                    JJLog.error(`(${requestCount})` + '【Response Faile】url: ' + url + '; error: ' + JSON.stringify(error));
                    JJRequestAgent.shareInstance().handleNetworkFailRequestResult(request, error);
                },
            })
        }
    }

    __startGetSecretkeyIfNeeded(request) {
        if (JJUtil.isNotNull(JJLoginService.shareInstance().getSecretkey())) {
            this.__startNoPasswordLoginIfNeeded(request)
            return
        }

        if (JJLoginService.JJLoginServiceIdentityGetSecretkey != request.identity) {
            this.addRequestToReadyRequestList(request)
        }

        const me = this
        JJLoginService.shareInstance().requestSecretkey((isSuccess, value, otherInfo) => {
            if (isSuccess) {
                me.__startNoPasswordLoginIfNeeded(request)
            } else {
                me.__startReadyRequestList()
            }
        }, (error, otherInfo) => {
            me.__startReadyRequestList()
        })
    }

    __startNoPasswordLoginIfNeeded(request) {
        if (JJLoginService.JJLoginServiceIdentityNoPasswordLogin != request.identity) {
            this.addRequestToReadyRequestList(request)
        }

        const me = this
        JJLoginService.shareInstance().isNeedNoPasswordLogin().then((value) => {
            if (value.isNeed) {
                JJLoginService.shareInstance().requestNoPasswordLogin({ regId: value.regId }, (isSuccess, value, otherInfo) => {
                    me.__startReadyRequestList()
                }, (error, otherInfo) => {
                    me.__startReadyRequestList()
                })
            } else {
                me.__startReadyRequestList()
            }
        })    
    }

    __startReadyRequestList() {
        const length = this.readyRequestList.length
        for (let i = 0; i < length; ++i) {
            const request = this.readyRequestList[i]
            if (JJUtil.isNotNull(request)) {
                this.__start(request)
            }
        }

        this.readyRequestList = []
    }
}
